package com.yangfei.SportAssistant.mapProvider;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Handler;
import android.util.Log;
import android.view.MotionEvent;


public abstract class AsyncOverlay implements OverlayProvider
{
   private static final int OFFSET = 20;

   private static final String TAG = "GG.AsyncOverlay";

   /**
    * Handler provided by the MapActivity to recalculate graphics
    */
   private Handler mHandler;

   private GeoPointYf mGeoTopLeft;

   private GeoPointYf mGeoBottumRight;

   private int mWidth;

   private int mHeight;

   private Bitmap mActiveBitmap;

   private GeoPointYf mActiveTopLeft;

   private Point mActivePointTopLeft;

   private Bitmap mCalculationBitmap;

   private Canvas mCalculationCanvas;

   private Paint mPaint;

   private LoggerMap mLoggerMap;

   private SegmentOsmOverlay mOsmOverlay;

   private SegmentMapQuestOverlay mMapQuestOverlay;
   
   private GoogleOverlay mGoogleOverlay;
   
   private SegmentBaiduOverlay mBaiduOverlay;

   private int mActiveZoomLevel;

   private Runnable mBitmapUpdater = new Runnable()
   {
      public void run()
      {
         postedBitmapUpdater = false;
         mLoggerMap.postInvalidate();
      }
   };

   private boolean postedBitmapUpdater;

   AsyncOverlay(LoggerMap loggermap, Handler handler)
   {
      mLoggerMap = loggermap;
      mHandler = handler;

      mOsmOverlay = new SegmentOsmOverlay(mLoggerMap.getActivity(), mLoggerMap, this);
      mMapQuestOverlay = new SegmentMapQuestOverlay(this);
      mGoogleOverlay = new GoogleOverlay(mLoggerMap, this);
      mBaiduOverlay = new SegmentBaiduOverlay(this);
   }


   public void onDateOverlayChanged()
   {
      Log.d(TAG, "onDateOverlayChanged posted yet " + postedBitmapUpdater);
      if (!postedBitmapUpdater)
      {
         postedBitmapUpdater = true;
         mHandler.post(mBitmapUpdater);
      }
   }

   protected abstract void redrawOffscreen(Canvas asyncBuffer, LoggerMap loggermap);

   protected abstract void scheduleRecalculation();


   private void draw(Canvas canvas)
   {
  	 mLoggerMap.draw(canvas);
   }


   /**************************************/
   /** Multi map support **/
   /**************************************/

   public com.google.android.maps.Overlay getGoogleOverlay()
   {
      return mGoogleOverlay;
   }

   public org.osmdroid.views.overlay.Overlay getOSMOverlay()
   {
      return mOsmOverlay;
   }

   public com.mapquest.android.maps.Overlay getMapQuestOverlay()
   {
      return mMapQuestOverlay;
   }
   
   public com.baidu.mapapi.Overlay getBaiduOverlay()
   {
  	 return mBaiduOverlay;
   }

   protected abstract boolean commonOnTap(GeoPointYf tappedGeoPoint);

   static class GoogleOverlay extends com.google.android.maps.Overlay
   {
      AsyncOverlay mSegmentOverlay;
      LoggerMap mLoggerMap;
      public GoogleOverlay(LoggerMap map, AsyncOverlay segmentOverlay)

      {
         mLoggerMap = map;
         mSegmentOverlay = segmentOverlay;
      }

      public AsyncOverlay getGoogleOverlay()
      {
         return mSegmentOverlay;
      }

      @Override
      public void draw(Canvas canvas, com.google.android.maps.MapView mapView, boolean shadow)
      {
         if (!shadow)
         {
            mSegmentOverlay.draw(canvas);
         }
      }
   }
   
   static class SegmentOsmOverlay extends org.osmdroid.views.overlay.Overlay
   {
      AsyncOverlay mSegmentOverlay;
      LoggerMap mLoggerMap;

      public SegmentOsmOverlay(Context ctx, LoggerMap map, AsyncOverlay segmentOverlay)
      {
         super(ctx);
         mLoggerMap = map;
         mSegmentOverlay = segmentOverlay;
      }

      public AsyncOverlay getSegmentOverlay()
      {
         return mSegmentOverlay;
      }

      @Override
      public boolean onSingleTapUp(MotionEvent e, org.osmdroid.views.MapView openStreetMapView)
      {
         int x = (int) e.getX();
         int y = (int) e.getY();
         GeoPointYf tappedGeoPoint = mLoggerMap.fromPixels(x, y);
         return mSegmentOverlay.commonOnTap(tappedGeoPoint);
      }

      @Override
      protected void draw(Canvas canvas, org.osmdroid.views.MapView view, boolean shadow)
      {
         if (!shadow)
         {
            mSegmentOverlay.draw(canvas);
         }
      }
   }

   static class SegmentMapQuestOverlay extends com.mapquest.android.maps.Overlay
   {
      AsyncOverlay mSegmentOverlay;

      public SegmentMapQuestOverlay(AsyncOverlay segmentOverlay)
      {
         super();
         mSegmentOverlay = segmentOverlay;
      }

      public AsyncOverlay getSegmentOverlay()
      {
         return mSegmentOverlay;
      }

      @Override
      public boolean onTap(com.mapquest.android.maps.GeoPoint p, com.mapquest.android.maps.MapView mapView)
      {
      	 GeoPointYf tappedGeoPoint = new GeoPointYf(p.getLatitudeE6(), p.getLongitudeE6());
         return mSegmentOverlay.commonOnTap(tappedGeoPoint);
      }

      @Override
      public void draw(Canvas canvas, com.mapquest.android.maps.MapView mapView, boolean shadow)
      {
         if (!shadow)
         {
            mSegmentOverlay.draw(canvas);
         }
      }

   }
   
   static class SegmentBaiduOverlay extends com.baidu.mapapi.Overlay
   {
      AsyncOverlay mSegmentOverlay;

      public SegmentBaiduOverlay(AsyncOverlay segmentOverlay)
      {
         super();
         mSegmentOverlay = segmentOverlay;
      }

      public AsyncOverlay getSegmentOverlay()
      {
         return mSegmentOverlay;
      }

      @Override
      public boolean onTap(com.baidu.mapapi.GeoPoint p, com.baidu.mapapi.MapView mapView)
      {
      	 GeoPointYf tappedGeoPoint = new GeoPointYf(p.getLatitudeE6(), p.getLongitudeE6());
         return mSegmentOverlay.commonOnTap(tappedGeoPoint);
      }

      @Override
      public void draw(Canvas canvas, com.baidu.mapapi.MapView mapView, boolean shadow)
      {
         if (!shadow)
         {
            mSegmentOverlay.draw(canvas);
         }
      }

   }
   
   
}
